package top.jfunc.common.thread.monitor.adapter;

import top.jfunc.common.thread.monitor.CountedRejectedExecutionHandler;
import top.jfunc.common.thread.monitor.change.ParamChangeBean;
import top.jfunc.common.thread.monitor.change.ParamChangerUtil;
import top.jfunc.common.thread.monitor.change.ThreadPoolExecutorParamChangeAdapter;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 代理j.u.c原生线程池{@link ThreadPoolExecutor}，附加监控相关信息
 */
public class ThreadPoolExecutorMonitoredAdapter extends AbstractThreadPoolExecutorMonitoredAdapter {
    private final ThreadPoolExecutor delegate;

    public ThreadPoolExecutorMonitoredAdapter(ThreadPoolExecutor threadPoolExecutor, String service, String poolName) {
        super(service, poolName);
        this.delegate = threadPoolExecutor;
        this.delegate.setRejectedExecutionHandler(new CountedRejectedExecutionHandler(this.delegate.getRejectedExecutionHandler()));
    }

    @Override
    public int getActiveCount() {
        return this.delegate.getActiveCount();
    }

    @Override
    public int getMaximumPoolSize() {
        return this.delegate.getMaximumPoolSize();
    }

    @Override
    public long getCompletedTaskCount() {
        return this.delegate.getCompletedTaskCount();
    }

    @Override
    public int getPoolSize() {
        return this.delegate.getPoolSize();
    }

    @Override
    public int getCorePoolSize() {
        return this.delegate.getCorePoolSize();
    }

    @Override
    public int getLargestPoolSize() {
        return this.delegate.getLargestPoolSize();
    }

    @Override
    public long getKeepAliveTime(TimeUnit timeUnit) {
        return this.delegate.getKeepAliveTime(timeUnit);
    }

    @Override
    public boolean allowsCoreThreadTimeOut() {
        return this.delegate.allowsCoreThreadTimeOut();
    }

    @Override
    public long getTaskCount() {
        return this.delegate.getTaskCount();
    }

    @Override
    public int getQueueCapacity() {
        BlockingQueue<Runnable> blockingQueue = this.delegate.getQueue();
        return blockingQueue.remainingCapacity() + blockingQueue.size();
    }

    @Override
    public int getQueueSize() {
        return this.delegate.getQueue().size();
    }

    @Override
    public String getQueueClass() {
        return this.delegate.getQueue().getClass().getName();
    }

    @Override
    public String getThreadFactoryClass() {
        return this.delegate.getThreadFactory().getClass().getName();
    }

    @Override
    public String getRejectedExecutionHandlerClass() {
        return RejectedExecutionHandlerUtil.getOriginalRejectedExecutionHandlerClass(this.delegate.getRejectedExecutionHandler());
    }

    @Override
    public int getRejectedCount() {
        return RejectedExecutionHandlerUtil.getRejectedCount(this.delegate.getRejectedExecutionHandler());
    }

    @Override
    public void resetStatistic() {
        RejectedExecutionHandlerUtil.resetRejectedCount(this.delegate.getRejectedExecutionHandler());
    }

    @Override
    public void onChange(ParamChangeBean bean) {
        ParamChangerUtil.paramChange(new ThreadPoolExecutorParamChangeAdapter(this.delegate), bean);
    }
}
